from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown as basDropDown
from kivy.uix.textinput import TextInput

from kivy.properties import ObjectProperty, ListProperty, BooleanProperty, StringProperty, NumericProperty


from kivy.event import EventDispatcher

class DropDown(basDropDown):
    offset = 0
    def _reposition(self,*largs):
        basDropDown._reposition(self,*largs)
        if self.offset:
            self.y = self.y+self.offset

def _keyboard_on_key_down(self, window, keycode, text, modifiers):
    key, key_str = keycode
    if key == 274:
        self.focus = False
        self.combo.select_first()
        return True
    return super(self.__class__, self)._keyboard_on_key_down(window, keycode, text, modifiers)

class ComboBoxBase(EventDispatcher):

    content = ListProperty([])
    editable = BooleanProperty(False)

    unlocalize = ObjectProperty(False) # necessary when embeded in a scatter widget

    textInputClass = ObjectProperty(TextInput) # must have the 'text' attribute !
    #ListViewClass = ObjectProperty(MyListView)
    entryWidClass  = ObjectProperty(Button) # must have the 'text' attribute !

    internSpacing = NumericProperty(2)
    padding = NumericProperty(2)
    parentscatter = None

    #textInputClass = ObjectProperty(TextInput) # must have the 'text' attribute !
    selected_index = -1
    
    def __init__(self, **kargs):
        self._initing = True
        super(ComboBoxBase,self).__init__(**kargs)
        self.textInputClass = type( 'Combo'+self.textInputClass.__name__, ( self.textInputClass, ) ,{'combo':self})
        #self.textInputClass._keyboard_on_key_down = _keyboard_on_key_down
        self.textInput = self.textInputClass(size=self.size, pos=self.pos, size_hint=(1,None), multiline=False)
        self.textInput.bind(on_text_validate=lambda *l : self.dispatch('on_input_validated'))
        
        self.register_event_type('on_choice_validated')
        self.register_event_type('on_input_validated')
        self._createDropDown()
        
        self.bind(on_release = self.buildDropDown)
        def showDD(*l):
            print ' showDD : ',self.dropdown, self.dropdown.pos,self.dropdown.size
        #self.bind(on_release = showDD)
        self._widContent = []

    def _createDropDown(self):
        self.dropdown = DropDown()
        self.dropdown.container.spacing = self.internSpacing
        self.dropdown.container.padding = self.padding
        self._dropdownready = False
        self.bind(on_release = self.dropdown.open)
        self.selected_index = -1


    def buildDropDown(self, *l):
        if self._dropdownready:
            return
        self.selected_index = -1
        dropdown = self.dropdown
        if self.editable:            
            dropdown.add_widget(self.textInput)
            dropdown.offset = self.textInput.height
        self._widContent = []
        for i,cont in enumerate(self.content):
            item = self.entryWidClass(text=cont)
            item._comboIndex = i
            item.size_hint_y=None
            item.bind(on_release = lambda item : dropdown.select(item._comboIndex))
            dropdown.add_widget(item)
            self._widContent.append(item)

        def ddselectChanged(instance, i):
            self.textInput.text = self._widContent[i].text 
            self.selected_index = i
            self.dispatch('on_input_validated')
        dropdown.bind(on_select= ddselectChanged)
        self._dropdownready = True



    def select_first(self):
        self.select_index(0)
    def select_index(self,i):
        self.buildDropDown()
        self.dropdown.select(i)

    def set_focus(self,*l):
        #print 'AAA combobox set_focus',self
        self.buildDropDown()
        self.textInput.focus = True        
        self.dropdown.open(self)

    def change_content(self, newcontent):
        #print '33333333 change content ! ',self, [newcontent]

        if self.content == newcontent:
            return
        self.content = newcontent
        if self._dropdownready and self.editable:
            self.dropdown.remove_widget(self.textInput)
            self.unbind(on_release = self.dropdown.open)

        self._createDropDown()


    def on_input_validated(self):
        self.text = self.textInput.text.decode('utf-8') ## with kivy 1.8 TextInput.text returns an ascii if given unicode !
        #print '33333 on_input_validated ', self, [self.textInput.text], [self.text]
        self.dropdown.dismiss()
        self.dispatch('on_choice_validated')


    
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if touch.button in( 'scrollup', 'scrolldown'):
                self.buildDropDown()
                if touch.button == 'scrolldown':
                    self.selected_index = max(self.selected_index -1, 0)
                    self.select_index(self.selected_index)
                else:
                    self.selected_index = min(self.selected_index +1, len(self._widContent)-1)
                    self.select_index(self.selected_index)
                self.dispatch('on_choice_validated')
                return
        return super(ComboBoxBase, self).on_touch_down(touch)


    def on_choice_validated(self):
        pass

    
class ComboBox(ComboBoxBase, Button):
    pass
